﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace DO.Workflows
{
    public static class ComponentsRegister
    {
        /// <summary>
        /// type name (without namespace) --> component type
        /// </summary>
        private static Dictionary<string, Type> componentTypes;

        /// <summary>
        /// works only if it's deployed as ASP.net application (including IIS hosted WCF projects)
        /// dll is deployed to: C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\site name\***\assembly
        /// </summary>
        static void InitComponents()
        {
            componentTypes = new Dictionary<string, Type>();
            string dllFilePath = typeof(WorkflowComponentBase).Assembly.Location;
            DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(dllFilePath));
            while (dir.Name.ToLower() != "assembly" && dir.Parent != null)
            {
                dir = dir.Parent;
            }
            if (dir.Name.ToLower() == "assembly")
            {
                FileInfo[] dllInfos = dir.GetFiles("*.dll", SearchOption.AllDirectories);
                foreach (FileInfo dllInfo in dllInfos)
                {
                    try
                    {
                        Assembly assembly = Assembly.LoadFile(dllInfo.FullName);
                        Type[] types = assembly.GetTypes();
                        foreach (Type type in types)
                        {
                            if (type.IsSubclassOf(typeof(WorkflowComponentBase)) && !type.IsAbstract)
                                ComponentTypes.Add(type.Name, type);
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }

        public static Dictionary<string, Type> ComponentTypes
        {
            get
            {
                if (componentTypes == null)
                    InitComponents();
                return componentTypes;
            }
        }
    }
}
